package org.ns.summer.mvc.mappinghandler;

import org.ns.summer.mvc.dynamicexec.DynamicExecute;
import org.ns.summer.mvc.dynamicexec.ExecParamInfo;
import org.ns.summer.mvc.dynamicexec.ExecParamTemplate;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.List;

/**
 * 处理执行
 */
public class HandlerExecutionChain {

    private HandlerMethod handlerMethod;
    private List<ExecParamTemplate> paramTemplates; //  参数执行模版
    private List<HandlerInterceptor> handlerInterceptors;
    public HandlerExecutionChain(HandlerMethod handlerMethod, List<ExecParamTemplate> paramTemplates, List<HandlerInterceptor> handlerInterceptors) {
        this.handlerMethod = handlerMethod;
        this.paramTemplates = paramTemplates;
        this.handlerInterceptors = handlerInterceptors;
    }

    public ExecutorResult executor(HttpServletRequest request, HttpServletResponse response) throws Throwable {

        // 动态参数执行
        DynamicExecute dynamicExecute = new DynamicExecute(new ExecParamTemplate() {
            @Override
            public Object paramLoad(ExecParamInfo autoParamInfo) throws Exception {
                Class<?> paramType = autoParamInfo.getParamType();
                if (paramType.isInstance(request)) {
                    return request;
                }
                if (paramType.isInstance(response)) {
                    return response;
                }
                Object value = null;
                // 通过自定义参数模版封装
                for (ExecParamTemplate paramTemplate : paramTemplates) {
                    if (paramTemplate.preHandle(autoParamInfo)) {
                        value = paramTemplate.paramLoad(autoParamInfo);
                    }
                    if (value != null) {
                        break;
                    }
                }
                return value;
            }
        });
        dynamicExecute.put(HttpServletRequest.class, request);
        dynamicExecute.put(HttpServletResponse.class, response);
        Object obj = handlerMethod.getObject();
        Method method = handlerMethod.getMethod();
        Object result = dynamicExecute.invoke(obj, method);
        return new ExecutorResult(result, handlerMethod);
    }

    public HandlerMethod getHandlerMethod() {
        return handlerMethod;
    }

    public List<HandlerInterceptor> getHandlerInterceptors() {
        return handlerInterceptors;
    }

    public boolean preHandler(HttpServletRequest request, HttpServletResponse response) {
        for (HandlerInterceptor handlerInterceptor : handlerInterceptors) {
            if (!handlerInterceptor.preHandler(request, response, handlerMethod)) {
                return false;
            }
        }
        return true;
    }
}
